//
// Created by admin on 2024/5/9.
//

#include "PingPongBuffer.h"
#include <string.h>

PingPongBuffer::PingPongBuffer(uint32_t size) {
    memset(&buffer, 0, sizeof(Buffer_t));

    if (size == 0) {
        return;
    }

    auto *p_buffer = new uint8_t[size * 2];

    if (p_buffer != nullptr) {
        buffer.data[0] = p_buffer;
        buffer.data[1] = p_buffer + size;
        buffer.size = size;
    }
}


PingPongBuffer::~PingPongBuffer() {

    if (buffer.data[0] != nullptr) {
        delete[] buffer.data[0];
    }

//    if (buffer.data[1] != nullptr) {
//        delete[]buffer.data[1];
//    }

    memset(&buffer, 0, sizeof(Buffer_t));
}


void PingPongBuffer::WriteData(void *data, uint32_t size) {
    buffer.writeIndex = !buffer.writeIndex;
    buffer.available[buffer.writeIndex] = false;

    void *buf = buffer.data[buffer.writeIndex];
    if (buf == nullptr) {
        return;
    }

    size = (size > buffer.size) ? buffer.size : size;
    memcpy(buf, data, size);

    buffer.available[buffer.writeIndex] = true;

}

bool PingPongBuffer::ReadData(void *data, uint32_t size) {
    uint8_t read = !buffer.writeIndex;
    if (buffer.available[read]) {
        buffer.readIndex = read;
    } else if (buffer.available[!read]) {
        buffer.readIndex = !read;
    } else {
        return false;
    }

    size = (size > buffer.size) ? buffer.size : size;
    memcpy(data, buffer.data[buffer.readIndex], size);

    buffer.available[buffer.readIndex] = false;

    return true;
}

PingPongBuffer::Buffer_t *PingPongBuffer::GetCache() {
    return &buffer;
}

bool PingPongBuffer::GetReadBuff(void **pReadBuf) {
    uint8_t read = !buffer.writeIndex;
    if (buffer.available[read]) {
        buffer.readIndex = read;
    } else if (buffer.available[!read]) {
        buffer.readIndex = !read;
    } else {
        return false;
    }

    *pReadBuf = buffer.data[buffer.readIndex];
    return true;
}

void PingPongBuffer::ReadDone() {
    buffer.available[buffer.readIndex] = false;
}
